#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/3/12 10:15
# @Author  : 一Carrycao
# @File    : base_def.py
# @Software: PyCharm
import minium


class BaseDef(minium.MiniTest):
    """定义基础操作"""


    def get_element_xpath(self, selector, timeout=10):
        """
        尝试根据提供的选择器和超时时间获取元素的XPath。

        参数:
        - selector: 用于定位元素的选择器。
        - timeout: 等待元素出现的超时时间，默认为10秒。

        返回值:
        - 如果找到元素，则返回该元素；如果未找到元素或发生异常，则返回None。
        """
        try:
            # 检查元素是否在指定超时时间内存在
            element_exists = self.app.current_page.element_is_exists(selector, max_timeout=timeout)

            if element_exists:
                # 如果元素存在，则尝试获取该元素
                ret = self.app.current_page.get_element(selector)
            else:
                # 如果元素不存在，则打印警告信息并返回None
                print(f"警告：在超时{timeout}秒后，未能找到匹配XPath表达式'{selector}'的元素")
                ret = None

        except AttributeError as ae:
            # 捕获并处理没有get_element方法的异常
            print(f"错误：当前页面对象未定义get_element方法: {ae}")
            ret = None
        except Exception as e:
            # 捕获并处理其他未知异常
            print(f"错误：在尝试获取XPath为'{selector}'的元素时发生未知异常: {e}")
            ret = None

        return ret

    def input_text(self, xpath, text):
        """
        输入文本到指定的输入框元素

        Parameters:
            xpath (str): 元素的XPath路径
            text (str): 要输入的文本内容

        Returns:
            input_element: 输入框元素对象，如果元素不存在则返回None
        """
        # 获取指定XPath的元素
        input_element = self.get_element_xpath(xpath)

        # 如果元素存在，则输入文本内容
        if input_element:
            input_element.input(text)
        else:
            # 如果元素不存在，则打印错误消息
            print(f"无法找到指定XPath的元素({xpath})进行输入操作")

        return input_element

    def swipe_element(self, x_offset, y_offset, duration, start_element_xpath=None, timeout=10):
        """
        在指定元素上执行滑动操作。

        参数:
        - x_offset: 水平方向的偏移量
        - y_offset: 垂直方向的偏移量
        - duration: 滑动操作持续的时间（秒）
        - start_element_xpath: 起始元素的XPath定位字符串，如果为None，则从当前视图中选择
        - timeout: 等待元素出现的超时时间（秒）

        返回值:
        - 如果找到并执行了滑动操作，则返回元素对象；否则返回None。
        """
        element = self.get_element_xpath(start_element_xpath)  # 根据XPath定位尝试获取元素
        if element:
            # 对找到的元素执行滑动操作
            element.move(x_offset, y_offset, duration, False)
            return element
        else:
            # 如果未找到指定的元素，则打印错误信息并返回None
            print(f"无法找到指定XPath的元素({start_element_xpath})进行滑动操作")
            return None

    def find_and_click_or_swipe(self, xpath, max_swipes=5):
        """
        尝试查找并点击一个元素，如果找不到则向下滚动屏幕并重试。

        参数:
        - xpath: 要查找的元素的XPath表达式
        - max_swipes: 最大滑动次数，默认为5次
        """
        for _ in range(max_swipes):
            # 尝试获取元素
            element = self.get_element_xpath(xpath)
            if element:
                # 找到元素，点击它
                element.click()
                print("元素已找到并点击。")
                return True  # 成功点击，退出循环
            else:
                # 元素未找到，尝试滑动屏幕
                print("元素未找到，准备滑动屏幕。")
                # 假设向下滚动一个屏幕高度，你可以根据实际情况调整x_offset和y_offset
                self.swipe_element(0, 500, 1)  # 垂直滑动500像素，持续1秒
        print("达到最大滑动次数，仍未找到元素。")
        return False

    # def _monitor_for_error_toast(self, stop_event, error_message="操作失败"):
    #     """
    #     后台线程方法，用于持续监控错误Toast。
    #     :param stop_event: 用于控制线程退出的事件对象
    #     :param error_message: 需要监控的错误消息文本，默认为"操作失败"
    #     """
    #     while not stop_event.is_set():
    #         try:
    #             error_toast_xpath = f'//*[contains(@text, "{error_message}")]'
    #             error_toast = self.get_element_xpath(error_toast_xpath)
    #             if error_toast.is_displayed():
    #                 self.fail("检测到操作失败的Toast，测试用例失败")
    #                 stop_event.set()  # 设置事件，停止主流程
    #         except NoSuchElementException:
    #             # 如果没有找到错误Toast，则继续监控
    #             pass
    #         except Exception as e:
    #             print(f"监控过程中出现异常: {e}")
    #             stop_event.set()
    #         finally:
    #             time.sleep(1)  # 控制检查频率，避免过于频繁的查询影响性能
    #
    # def start_toast_monitor(self, error_message="操作失败"):
    #     """
    #     启动错误Toast的后台监控线程。
    #     """
    #     stop_event = threading.Event()
    #     toast_monitor_thread = threading.Thread(target=self._monitor_for_error_toast, args=(stop_event, error_message))
    #     toast_monitor_thread.daemon = True  # 设置为守护线程，主程序结束时自动关闭
    #     toast_monitor_thread.start()
    #     return stop_event

